package cn.mujiankeji.mbrowser.界面.组件.布局

import android.view.Window
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.max
import cn.mujiankeji.mbrowser.工具.clickable2
import cn.mujiankeji.mbrowser.界面.组件.系统底部空间占位
import cn.mujiankeji.mbrowser.界面.组件.系统虚拟导航栏占位
import 界面.组件.按钮.取消图标按钮
import 界面.组件.按钮.取消按钮
import 界面.组件.按钮.确认图标按钮
import 界面.组件.按钮.确认按钮
import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.roundToInt
import androidx.compose.runtime.rememberCoroutineScope
import kotlinx.coroutines.launch

@Composable
fun 输入窗口布局(销毁 : ()->Unit,
                 提交 : ()->Unit,
                 内容 : @Composable ColumnScope.()->Unit){

    Column(modifier = Modifier.fillMaxSize()
        .background(Color.Black.copy(0.3f))){

        Spacer(
            Modifier.fillMaxWidth()
            .weight(1f)
            .clickable2{销毁()})

        // 圆角设计 -- 基本的内容小窗口
        Surface(
            shape = RoundedCornerShape(topEnd = 12.dp, topStart = 12.dp),
            shadowElevation = 3.dp,
            modifier = Modifier
                .padding(top = 3.dp),
        ) {
            Column(
                Modifier
                    .background(MaterialTheme.colorScheme.surface)
                    .fillMaxWidth()
            )
            {
                内容()

                Box(
                    Modifier.fillMaxWidth()
                        .padding(horizontal = 20.dp)
                        .height(50.dp), contentAlignment = Alignment.CenterEnd){
                    Row{

                        Spacer(Modifier.weight(1f))
                        取消图标按钮 { 销毁() }
                        Spacer(Modifier.width(20.dp))
                        确认图标按钮 { 提交() }
                    }
                }
            }

        }

        // 添加系统底部空间占位，确保窗口在虚拟导航栏上方
        Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
    }
}


/**
 * 通用底部窗口布局
 * @param 销毁 窗口被关闭
 * @param 自适应高度 是否根据内容自适应高度，为false时使用固定高度比例
 * @param contentPaddingValues 内容区域的内边距
 */
@Composable
fun 底部窗口布局(销毁 : (()->Unit)?=null,
                 自适应高度: Boolean = false,
                 自适应键盘高度 : Boolean = 自适应高度,
                 contentPaddingValues: PaddingValues = PaddingValues(0.dp),
                 内容 : @Composable ColumnScope.()->Unit){
    
    // 添加状态来控制偏移量
    var offsetY by remember { mutableStateOf(0f) }
    var isDragging by remember { mutableStateOf(false) }
    val dismissThreshold = 100.dp.value

    // 使用动画使移动更流畅
    val animatedOffsetY by animateFloatAsState(
        targetValue = if (isDragging) offsetY else 0f,
        animationSpec = tween(
            durationMillis = if (!isDragging && offsetY > 0) 300 else 0
        ),
        label = "offsetAnimation"
    )

    // 计算背景透明度
    val backgroundAlpha = (0.3f * (1f - (animatedOffsetY / 1000f))).coerceIn(0f, 0.3f)

    Column(modifier = Modifier.fillMaxSize()
        .background(Color.Black.copy(backgroundAlpha))
    ) {

        Spacer(
            Modifier.fillMaxWidth()
                .weight(1f)
                .clickable2 { 销毁?.invoke() })

        Surface(
            shape = RoundedCornerShape(topEnd = 16.dp, topStart = 16.dp),
            color = MaterialTheme.colorScheme.background,
            shadowElevation = 3.dp,
            modifier = Modifier.fillMaxWidth()
                // 根据自适应高度参数决定是否使用固定高度比例
                .then(if (!自适应高度) Modifier.fillMaxHeight(0.68f) else Modifier)
                .offset { IntOffset(0, animatedOffsetY.roundToInt()) }
                .pointerInput(Unit) {
                    detectDragGestures(
                        onDragStart = { isDragging = true },
                        onDragEnd = {
                            isDragging = false
                            // 如果拖动距离超过阈值，触发取消
                            if (offsetY > dismissThreshold) {
                                销毁?.invoke()
                            }
                            // 重置偏移量
                            offsetY = 0f
                        },
                        onDragCancel = {
                            isDragging = false
                            offsetY = 0f
                        },
                        onDrag = { change, dragAmount ->
                            // 只响应向下拖动
                            if (dragAmount.y > 0) {
                                offsetY += dragAmount.y
                            } else if (offsetY > 0 && dragAmount.y < 0) {
                                // 向上拖动时，如果已经有向下的偏移，则减少偏移
                                offsetY = (offsetY + dragAmount.y).coerceAtLeast(0f)
                            }
                        }
                    )
                }
                .clickable2 {  },
        ) {
            Column(
                // 根据自适应高度参数决定是否填充整个可用空间
                modifier = if (自适应高度) Modifier.wrapContentHeight() else Modifier.fillMaxSize()
            ){

                Box(Modifier.fillMaxWidth().height(35.dp), contentAlignment = Alignment.Center){
                    Spacer(Modifier.width(35.dp).height(3.dp).background(MaterialTheme.colorScheme.secondary,
                        CircleShape
                    ))
                }

                Spacer(Modifier.height(10.dp))

                Column(Modifier.padding(paddingValues = contentPaddingValues)
                    // 根据自适应高度参数决定是否使用weight来填充剩余空间
                    .then(if (!自适应高度) Modifier.weight(1f) else Modifier)
                    .fillMaxWidth()) {
                    内容()
                }

                // 添加系统底部空间占位，确保窗口在虚拟导航栏上方
                系统虚拟导航栏占位()

            }
        }

        if (自适应高度){
            Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
        }


    }
}

@Composable
fun 底部窗口布局2(销毁 : (()->Unit)?=null,
                 自适应高度: Boolean = false,
                 自适应键盘高度 : Boolean = 自适应高度,
                 contentPaddingValues: PaddingValues = PaddingValues(0.dp),
                 内容 : @Composable ColumnScope.()->Unit){

    // 添加状态来控制偏移量
    var offsetY by remember { mutableStateOf(0f) }
    var isDragging by remember { mutableStateOf(false) }
    val dismissThreshold = 100.dp.value

    // 使用动画使移动更流畅
    val animatedOffsetY by animateFloatAsState(
        targetValue = if (isDragging) offsetY else 0f,
        animationSpec = tween(
            durationMillis = if (!isDragging && offsetY > 0) 300 else 0
        ),
        label = "offsetAnimation"
    )

    // 计算背景透明度
    val backgroundAlpha = (0.3f * (1f - (animatedOffsetY / 1000f))).coerceIn(0f, 0.3f)

    Column(modifier = Modifier.fillMaxSize()
        .background(Color.Black.copy(backgroundAlpha))
    ) {

        Spacer(
            Modifier.fillMaxWidth()
                .weight(1f)
                .clickable2 { 销毁?.invoke() })

        Surface(
            shape = RoundedCornerShape(16.dp),
            color = MaterialTheme.colorScheme.surface,
            shadowElevation = 3.dp,
            modifier = Modifier
                .padding(15.dp)
                .fillMaxWidth()
                // 根据自适应高度参数决定是否使用固定高度比例
                .offset { IntOffset(0, animatedOffsetY.roundToInt()) }
                .pointerInput(Unit) {
                    detectDragGestures(
                        onDragStart = { isDragging = true },
                        onDragEnd = {
                            isDragging = false
                            // 如果拖动距离超过阈值，触发取消
                            if (offsetY > dismissThreshold) {
                                销毁?.invoke()
                            }
                            // 重置偏移量
                            offsetY = 0f
                        },
                        onDragCancel = {
                            isDragging = false
                            offsetY = 0f
                        },
                        onDrag = { change, dragAmount ->
                            // 只响应向下拖动
                            if (dragAmount.y > 0) {
                                offsetY += dragAmount.y
                            } else if (offsetY > 0 && dragAmount.y < 0) {
                                // 向上拖动时，如果已经有向下的偏移，则减少偏移
                                offsetY = (offsetY + dragAmount.y).coerceAtLeast(0f)
                            }
                        }
                    )
                }
                .clickable2 {  },
        ) {
            Column(
                // 根据自适应高度参数决定是否填充整个可用空间
                modifier = Modifier
                    .wrapContentHeight()
            ){

                Box(Modifier.fillMaxWidth().height(35.dp), contentAlignment = Alignment.Center){
                    Spacer(Modifier.width(35.dp).height(3.dp).background(MaterialTheme.colorScheme.secondary,
                        CircleShape
                    ))
                }

                Spacer(Modifier.height(10.dp))

                Column(Modifier.padding(paddingValues = contentPaddingValues)
                    // 根据自适应高度参数决定是否使用weight来填充剩余空间
                    .then(if (!自适应高度) Modifier.weight(1f) else Modifier)
                    .fillMaxWidth()) {
                    内容()
                }

                Spacer(Modifier.height(20.dp))

            }
        }

        Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))

        if (自适应键盘高度){
            Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
        }


    }
}




/**
 * 仿IOS的窗口布局，可用户完整的配置页面
 */
@Composable
fun IOS窗口布局(
    销毁: (() -> Unit)? = null,
    提交: (() -> Unit)? = null,
    标题: String = "",
    显示取消按钮: Boolean = 提交 != null,
    显示完成按钮: Boolean = 提交 != null,
    完成按钮文本: String = "完成",
    内容: @Composable ColumnScope.() -> Unit
) {
    // 添加状态来控制偏移量和缩放
    var offsetY by remember { mutableStateOf(0f) }
    var isDragging by remember { mutableStateOf(false) }
    var shouldClose by remember { mutableStateOf(false) }
    var dragDirection by remember { mutableStateOf(0) } // -1: 上, 0: 无, 1: 下
    val velocityTracker = remember { VelocityTracker() }
    var lastVelocity by remember { mutableStateOf(0f) }

    // 关闭阈值参数
    val distanceThreshold = 150.dp.value  // 距离阈值
    val velocityThreshold = 300f  // 速度阈值，单位为px/秒

    // 动画规格，根据是否关闭使用不同的规格
    val animationSpec: AnimationSpec<Float> = if (shouldClose) {
        // 关闭时使用较快的动画
        tween(durationMillis = 200)
    }
    else {
        // 回弹时使用弹簧动画，更自然
        spring(
            dampingRatio = 0.8f,  // 阻尼比，控制回弹的"弹性"
            stiffness = 300f      // 刚度，控制回弹的速度
        )
    }

    // 计算目标位置
    val targetY = if (shouldClose) 1000f else 0f

    // 使用动画使移动更流畅
    val animatedOffsetY by animateFloatAsState(
        targetValue = if (isDragging) offsetY else targetY,
        animationSpec = animationSpec,
        finishedListener = {
            // 动画结束后，如果应该关闭，则调用取消函数
            if (shouldClose) {
                销毁?.invoke()
            }
        },
        label = "offsetAnimation"
    )

    // 计算背景透明度，使用非线性渐变更自然
    val backgroundAlpha = (0.5f * (1f - (animatedOffsetY / 500f).coerceIn(0f, 1f)).pow(1.5f)).coerceIn(0f, 0.5f)

    // 阻尼函数，使拖动在较大距离时变得更困难，模拟iOS的体验
    fun applyDamping(delta: Float): Float {
        return delta * (1f - (offsetY / 1500f).coerceIn(0f, 0.8f))
    }

    Box(modifier = Modifier.fillMaxSize()) {
        // 半透明背景
        Box(
            Modifier.fillMaxSize()
                .background(Color.Black.copy(backgroundAlpha))
                .clickable2 {
                    // 点击背景时设置shouldClose为true并重置拖动状态
                    shouldClose = true
                    isDragging = false
                }
        )

        // 内容窗口 - iOS风格使用更大的圆角但是几乎占满全屏，并考虑系统状态栏和导航栏
        Surface(
            shape = RoundedCornerShape(16.dp),
            color = MaterialTheme.colorScheme.background,
            shadowElevation = 10.dp,
            modifier = Modifier
                .windowInsetsPadding(WindowInsets.safeDrawing)  // 应用安全绘制区域的内边距
                .fillMaxWidth(0.98f)
                .fillMaxHeight(0.99f)  // 稍微缩小高度以适应系统栏
                .align(Alignment.Center)
                .offset { IntOffset(0, animatedOffsetY.roundToInt()) }
                .pointerInput(Unit) {
                    detectDragGestures(
                        onDragStart = {
                            isDragging = true
                            velocityTracker.resetTracking()
                            dragDirection = 0
                        },
                        onDragEnd = {
                            isDragging = false

                            // iOS风格：最后的移动方向是关键
                            // 如果最后一次拖动是向上的，则永远不关闭
                            if (dragDirection == -1) {
                                shouldClose = false
                                offsetY = 0f
                                return@detectDragGestures
                            }

                            // 只有当最后一次拖动是向下时，才考虑关闭
                            if (dragDirection == 1) {
                                val exceedsDistanceThreshold = offsetY > distanceThreshold
                                val exceedsVelocityThreshold = lastVelocity > velocityThreshold
                                shouldClose = exceedsDistanceThreshold || exceedsVelocityThreshold
                            } else {
                                shouldClose = false
                            }

                            // 如果不关闭，回到原位
                            if (!shouldClose) {
                                offsetY = 0f
                            }
                        },
                        onDragCancel = {
                            isDragging = false
                            shouldClose = false
                            offsetY = 0f
                            dragDirection = 0
                        },
                        onDrag = { change, dragAmount ->
                            change.consume()

                            // 记录当前拖动方向
                            dragDirection = when {
                                dragAmount.y > 1f -> 1  // 向下拖动
                                dragAmount.y < -1f -> -1 // 向上拖动
                                else -> dragDirection  // 保持原方向
                            }

                            // 更新速度追踪器
                            velocityTracker.addPosition(
                                change.uptimeMillis,
                                change.position
                            )

                            // 计算当前Y方向的速度
                            val velocity = velocityTracker.calculateVelocity()
                            lastVelocity = velocity.y

                            // 垂直拖动时的处理逻辑改进
                            if (dragAmount.y > 0) {
                                // 向下拖动，应用阻尼效果
                                offsetY += applyDamping(dragAmount.y)
                            } else if (dragAmount.y < 0) {
                                // 向上拖动时应用更强的反向力，使其更容易回到原位
                                // iOS风格：向上拖动应更敏感，给用户明确的"取消关闭"反馈
                                offsetY = (offsetY + dragAmount.y * 1.5f).coerceAtLeast(0f)
                            }
                        }
                    )
                },
        ) {
            // iOS风格的内容区域通常有内边距，并考虑安全区域
            Column(
                Modifier
                    .fillMaxSize()
                    .padding(horizontal = 8.dp, vertical = 18.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                // 顶部拖动条 - iOS风格
                Spacer(
                    Modifier
                        .width(36.dp)
                        .height(5.dp)
                        .background(
                            MaterialTheme.colorScheme.outline,
                            CircleShape
                        )
                )

                Spacer(Modifier.height(16.dp))

                // iOS风格的导航栏 - 包含标题、取消和完成按钮
                if (标题.isNotEmpty() || 显示取消按钮 || 显示完成按钮) {
                    Box(
                        Modifier
                            .fillMaxWidth()
                            .padding(horizontal = 8.dp)
                    ) {
                        // 左侧取消按钮
                        if (显示取消按钮) {
                            androidx.compose.material3.TextButton(
                                onClick = {
                                    // 点击取消按钮时设置shouldClose为true
                                    shouldClose = true
                                    isDragging = false
                                },
                                modifier = Modifier.align(Alignment.CenterStart)
                            ) {
                                androidx.compose.material3.Text(
                                    "取消",
                                    style = MaterialTheme.typography.bodyLarge,
                                    color = MaterialTheme.colorScheme.primary
                                )
                            }
                        }

                        // 中间标题
                        if (标题.isNotEmpty()) {
                            androidx.compose.material3.Text(
                                标题,
                                style = MaterialTheme.typography.titleMedium,
                                modifier = Modifier.align(Alignment.Center)
                            )
                        }

                        // 右侧完成按钮
                        if (显示完成按钮) {
                            androidx.compose.material3.TextButton(
                                onClick = { 提交?.invoke() },
                                modifier = Modifier.align(Alignment.CenterEnd)
                            ) {
                                androidx.compose.material3.Text(
                                    完成按钮文本,
                                    style = MaterialTheme.typography.bodyLarge,
                                    color = MaterialTheme.colorScheme.primary,
                                    textDecoration = TextDecoration.Underline
                                )
                            }
                        }
                    }

                    // 分隔线
                    Spacer(Modifier.height(8.dp))
                    androidx.compose.material3.Divider(
                        color = MaterialTheme.colorScheme.outlineVariant,
                        thickness = 0.5.dp
                    )
                    Spacer(Modifier.height(16.dp))
                }

                // 用户内容
                内容()
            }
        }
    }
}


/**
 * 基于《底部窗口布局》增加 取消、提交 等内容
 */
@Composable
fun 配置窗口布局(标题 : String,
                 取消 : ()->Unit,
                 提交 : ()->Unit,
                 自适应高度: Boolean = false,
                 内容 : @Composable ColumnScope.()->Unit){
    底部窗口布局({取消()}, 自适应高度){
        Column(
            Modifier
                .background(MaterialTheme.colorScheme.surface)
                .fillMaxWidth()
        )
        {
            if (标题.isNotEmpty()){
                Box(Modifier.padding(vertical = 10.dp)
                    .fillMaxWidth(), contentAlignment = Alignment.Center){
                    Text(标题, style = MaterialTheme.typography.titleMedium,
                        color = MaterialTheme.colorScheme.onSurface)
                }
            }

            Column(Modifier.weight(1f).fillMaxWidth()){
                内容()
            }

            Row(Modifier.fillMaxWidth()
                .padding(15.dp)){
                取消按钮(Modifier.weight(1f), height = 38.dp){
                    取消()
                }
                Spacer(Modifier.width(15.dp))
                确认按钮(Modifier.weight(1f), height = 38.dp){
                    提交()
                }
            }

            Spacer(Modifier.height(15.dp))

        }


    }
    系统底部空间占位()


}



// 更新底部窗口状态枚举
enum class 底部窗口状态 {
    关闭,
    半展开,
    全展开
}